package jflowsim.view.configdialog;

import java.awt.Color;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.text.DecimalFormat;
import javax.swing.JTextField;
import jflowsim.controller.solverbuilder.SolverBuilder;
import jflowsim.controller.solverbuilder.SolverFactory;
import jflowsim.model.ModelManager;
import jflowsim.model.numerics.Solver;
import jflowsim.view.MainWindow;
import jflowsim.view.img.ImageUtilities;

public class ConfigDialog extends javax.swing.JDialog implements WindowListener {

    private boolean validation = true;
    private ModelManager model;
    java.awt.Frame parent;

    /** Creates new form ConfigDialog */
    public ConfigDialog(ModelManager model, java.awt.Frame _parent) {
        super(_parent, false);

        this.model = model;
        this.parent = _parent;

        initComponents();

        this.setIconImage(ImageUtilities.createImageIcon("config").getImage());

        this.addWindowListener(this);
    }

    private double getDoubleValueFromTextField(JTextField tf) {
        String str = tf.getText();
        tf.setBackground(Color.white);
        double value = -999.9;
        try {
            value = Double.parseDouble(str);
        } catch (NumberFormatException ex) {
            validation = false;
            tf.setBackground(Color.red);
        }
        return value;
    }

    private int getIntegerValueFromTextField(JTextField tf) {
        String str = tf.getText();
        tf.setBackground(Color.white);
        int value = -999;
        try {
            value = Integer.parseInt(str);
        } catch (NumberFormatException ex) {
            validation = false;
            tf.setBackground(Color.red);
        }
        return value;
    }

    public void update() {
        this.setParameterFromGrid2UI();
    }

    private void setParameterFromGrid2UI() {
        if (model.hasGrid()) {

            DecimalFormat dfExpo = new DecimalFormat("0.00E0");
            DecimalFormat df = new DecimalFormat("0.####");

            gravity_x_tf.setText(String.valueOf(model.grid.gravityX));
            gravity_y_tf.setText(String.valueOf(model.grid.gravityY));
            viscosity_tf.setText(dfExpo.format(model.grid.viscosity));
            delta_t_tf.setText(dfExpo.format(model.grid.dt));

            length_tf.setText(String.valueOf(model.grid.getLength()));
            width_tf.setText(String.valueOf(model.grid.getWidth()));
            delta_x_tf.setText(df.format(model.grid.dx));


            updateI_tf.setText(String.valueOf(model.grid.updateInterval));
            //writerU_tf
        }
    }

    private boolean applyParameter() {

        validation = true;

        if (model.hasGrid()) {

            double gravity_x = getDoubleValueFromTextField(gravity_x_tf);
            double gravity_y = getDoubleValueFromTextField(gravity_y_tf);
            double viscosity = getDoubleValueFromTextField(viscosity_tf);
            double delta_t = getDoubleValueFromTextField(delta_t_tf);

            double length = getDoubleValueFromTextField(length_tf);
            double width = getDoubleValueFromTextField(width_tf);
            double delta_x = getDoubleValueFromTextField(delta_x_tf);



            int update_interval = model.grid.updateInterval = getIntegerValueFromTextField(updateI_tf);
            int writer_update = getIntegerValueFromTextField(writerU_tf);


            if (validation) {
                model.grid.setGravity(gravity_x, gravity_y);
                model.grid.setViscosity(viscosity);
                model.grid.setTimeStep(delta_t);

                // set length, width, delta_x
                double scaleFactor = model.grid.dx / delta_x;
                if (scaleFactor != 1.0) {

                    String _solverName = model.solver.getClass().getSimpleName();
                    model.stopSimulation();

                    model.grid.refineGrid(scaleFactor);

                    if (this.fixedMachNumber_cb.isSelected()) {
                        model.grid.setTimeStep(delta_t / scaleFactor);
                        this.setParameterFromGrid2UI();
                    }

                    SolverBuilder builder = SolverFactory.getInstance().getBuilder(_solverName);
                    Solver solver = builder.createSolver(model.grid);
                    solver.addObserver(((MainWindow) this.parent).viewer);
                    model.grid.map2Grid(model);
                    model.startSimulation(solver);
                }


                model.grid.updateInterval = update_interval;


                model.grid.updateParameters();
            }
        }

        return validation;
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jSpinner1 = new javax.swing.JSpinner();
        apply_button = new javax.swing.JButton();
        ok_button = new javax.swing.JButton();
        cancel_button = new javax.swing.JButton();
        jPanel4 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        gravity_x_tf = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        gravity_y_tf = new javax.swing.JTextField();
        jLabel7 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        viscosity_tf = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        delta_t_tf = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
        jLabel24 = new javax.swing.JLabel();
        delta_x_tf = new javax.swing.JTextField();
        jLabel23 = new javax.swing.JLabel();
        jLabel25 = new javax.swing.JLabel();
        fixedMachNumber_cb = new javax.swing.JCheckBox();
        jPanel1 = new javax.swing.JPanel();
        jPanel6 = new javax.swing.JPanel();
        jLabel22 = new javax.swing.JLabel();
        length_tf = new javax.swing.JTextField();
        jLabel19 = new javax.swing.JLabel();
        jLabel20 = new javax.swing.JLabel();
        width_tf = new javax.swing.JTextField();
        jLabel21 = new javax.swing.JLabel();
        jPanel8 = new javax.swing.JPanel();
        jLabel26 = new javax.swing.JLabel();
        updateI_tf = new javax.swing.JTextField();
        jLabel28 = new javax.swing.JLabel();
        jLabel30 = new javax.swing.JLabel();
        writerU_tf = new javax.swing.JTextField();
        jLabel32 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("JFlowSim - ConfigDialog");
        setIconImage(null);
        setMinimumSize(new java.awt.Dimension(414, 442));
        setResizable(false);

        apply_button.setText("apply");
        apply_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                apply_buttonActionPerformed(evt);
            }
        });

        ok_button.setText("ok");
        ok_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                ok_buttonActionPerformed(evt);
            }
        });

        cancel_button.setText("cancel");
        cancel_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancel_buttonActionPerformed(evt);
            }
        });

        jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("physics"));
        jPanel4.setLayout(new java.awt.GridLayout(6, 3, 0, 8));

        jLabel2.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel2.setText("gravity in x");
        jPanel4.add(jLabel2);

        gravity_x_tf.setText("0.0");
        jPanel4.add(gravity_x_tf);

        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel1.setText("[m/s²]");
        jPanel4.add(jLabel1);

        jLabel6.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel6.setText("gravity in y");
        jPanel4.add(jLabel6);

        gravity_y_tf.setText("9.81");
        jPanel4.add(gravity_y_tf);

        jLabel7.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel7.setText("[m/s²]");
        jPanel4.add(jLabel7);

        jLabel3.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel3.setText("viscosity");
        jPanel4.add(jLabel3);

        viscosity_tf.setText("1.00");
        jPanel4.add(viscosity_tf);

        jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel4.setText("[m²/s]");
        jPanel4.add(jLabel4);

        jLabel8.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        jLabel8.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel8.setText("delta t");
        jPanel4.add(jLabel8);

        delta_t_tf.setText("1");
        delta_t_tf.setEnabled(false);
        jPanel4.add(delta_t_tf);

        jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel5.setText("[m]");
        jPanel4.add(jLabel5);

        jLabel24.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        jLabel24.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel24.setText("delta x");
        jPanel4.add(jLabel24);

        delta_x_tf.setText("0.1");
        jPanel4.add(delta_x_tf);

        jLabel23.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel23.setText("[m]");
        jPanel4.add(jLabel23);

        jLabel25.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        jLabel25.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel25.setText("ratio dx / dt");
        jPanel4.add(jLabel25);

        fixedMachNumber_cb.setSelected(true);
        fixedMachNumber_cb.setText("lock");
        fixedMachNumber_cb.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                fixedMachNumber_cbActionPerformed(evt);
            }
        });
        jPanel4.add(fixedMachNumber_cb);

        jPanel1.setLayout(new java.awt.GridLayout(1, 0));

        jPanel6.setBorder(javax.swing.BorderFactory.createTitledBorder("dimensions"));
        jPanel6.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        jPanel6.setLayout(new java.awt.GridLayout(2, 3, 0, 8));

        jLabel22.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel22.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel22.setText("length");
        jPanel6.add(jLabel22);

        length_tf.setEditable(false);
        length_tf.setText("1.0");
        length_tf.setEnabled(false);
        jPanel6.add(length_tf);

        jLabel19.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel19.setText("[m]");
        jPanel6.add(jLabel19);

        jLabel20.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel20.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel20.setText("width");
        jPanel6.add(jLabel20);

        width_tf.setEditable(false);
        width_tf.setText("1.0");
        width_tf.setEnabled(false);
        jPanel6.add(width_tf);

        jLabel21.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel21.setText("[m]");
        jPanel6.add(jLabel21);

        jPanel8.setBorder(javax.swing.BorderFactory.createTitledBorder("visualization"));
        jPanel8.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        jPanel8.setLayout(new java.awt.GridLayout(2, 3, 0, 8));

        jLabel26.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabel26.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel26.setText("update interval");
        jPanel8.add(jLabel26);

        updateI_tf.setText("100");
        jPanel8.add(updateI_tf);

        jLabel28.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel28.setText("[-]");
        jPanel8.add(jLabel28);

        jLabel30.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        jLabel30.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel30.setText("writer update");
        jPanel8.add(jLabel30);

        writerU_tf.setText("1000");
        writerU_tf.setEnabled(false);
        jPanel8.add(writerU_tf);

        jLabel32.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel32.setText("[-]");
        jPanel8.add(jLabel32);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanel4, javax.swing.GroupLayout.DEFAULT_SIZE, 388, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap())
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jPanel6, javax.swing.GroupLayout.DEFAULT_SIZE, 388, Short.MAX_VALUE)
                        .addGap(16, 16, 16))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(cancel_button)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(apply_button)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(ok_button))
                            .addComponent(jPanel8, javax.swing.GroupLayout.DEFAULT_SIZE, 388, Short.MAX_VALUE))
                        .addGap(16, 16, 16))))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(44, 44, 44)
                        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jPanel4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(18, 18, 18)
                .addComponent(jPanel6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel8, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(apply_button)
                    .addComponent(ok_button)
                    .addComponent(cancel_button))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void cancel_buttonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancel_buttonActionPerformed
        this.dispose();
    }//GEN-LAST:event_cancel_buttonActionPerformed

    private void apply_buttonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_apply_buttonActionPerformed
        applyParameter();
    }//GEN-LAST:event_apply_buttonActionPerformed

    private void ok_buttonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ok_buttonActionPerformed
        if (applyParameter()) {
            this.dispose();
        }
    }//GEN-LAST:event_ok_buttonActionPerformed

    private void fixedMachNumber_cbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fixedMachNumber_cbActionPerformed
       if( !fixedMachNumber_cb.isSelected() )
           delta_t_tf.setEnabled(true);
       else
           delta_t_tf.setEnabled(false);
    }//GEN-LAST:event_fixedMachNumber_cbActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton apply_button;
    private javax.swing.JButton cancel_button;
    private javax.swing.JTextField delta_t_tf;
    private javax.swing.JTextField delta_x_tf;
    private javax.swing.JCheckBox fixedMachNumber_cb;
    private javax.swing.JTextField gravity_x_tf;
    private javax.swing.JTextField gravity_y_tf;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel19;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel20;
    private javax.swing.JLabel jLabel21;
    private javax.swing.JLabel jLabel22;
    private javax.swing.JLabel jLabel23;
    private javax.swing.JLabel jLabel24;
    private javax.swing.JLabel jLabel25;
    private javax.swing.JLabel jLabel26;
    private javax.swing.JLabel jLabel28;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel30;
    private javax.swing.JLabel jLabel32;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JPanel jPanel8;
    private javax.swing.JSpinner jSpinner1;
    private javax.swing.JTextField length_tf;
    private javax.swing.JButton ok_button;
    private javax.swing.JTextField updateI_tf;
    private javax.swing.JTextField viscosity_tf;
    private javax.swing.JTextField width_tf;
    private javax.swing.JTextField writerU_tf;
    // End of variables declaration//GEN-END:variables

    public void windowOpened(WindowEvent e) {
    }

    public void windowClosing(WindowEvent e) {
    }

    public void windowClosed(WindowEvent e) {
    }

    public void windowIconified(WindowEvent e) {
    }

    public void windowDeiconified(WindowEvent e) {
    }

    public void windowActivated(WindowEvent e) {
        if (this.isVisible()) {
            setParameterFromGrid2UI();
        }
    }

    public void windowDeactivated(WindowEvent e) {
    }
}
